#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib
import re
import json
import logging
import redis
import datetime
import time
import os

from mitmproxy import http

log_path = "C:\pkg2"
if os.path.exists(log_path):
    log_file = os.path.join(log_path, 'sdk_' + str(
        datetime.datetime.now().strftime("%Y%m%d")) + '.log')
else:
    os.mkdir(r'%s' % log_path)
    log_file = os.path.join(log_path, 'sdk_' + str(
        datetime.datetime.now().strftime("%Y%m%d")) + '.log')

# 对日志的输出格式及方式做相关配置
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
    datefmt='%a, %d %b %Y %H:%M:%S',
    filename=log_file,
    filemode='a')

# 大陆联运操作名（从path中获取,如activity_open.php）
udpdcs_action_from_path = {
    'init_info': '初始化日志',
    'activity_open': '打开游戏日志',
    'activity_before_login': '登录界面前日志',
    'user_login': '登录日志',
    'enter_game': '进入游戏日志',
    'user_server_login': '选服日志',
    'user_create_role': '创角日志',
    'user_online': '在线日志',
    'role_level': '等级日志',
    'share': 'share',
    'share_log': 'share_log',
    'photo_share': '图片分享',
    'event': 'event',
    'gift_code': '礼包激活',
}

# 大陆sy操作名(从body中获取)
sdkdcs_action_from_data = {
    'open_game': '打开游戏日志',
    'open_login': '登录界面前日志',
    'select_server': '选服日志',
    'create_role': '创角日志',
    'role_level_change': '等级日志',
    'online': '在线日志',

}

# api 关键操作，如登录，注册
api_action_from_path = {
    # #海外平台 api.4399en.com
    'auto_login': '自动登录',
    'register': '注册接口',
    'direct_login': '免注册登录',
    'sdk_login': 'VK token登陆',
    'tmp_user_login': 'sydid免注册登录',
    'login_fb': 'FB登陆',
    'login_with_token': 'token登陆',
    'check_user': '查询用户是否绑定',
    'game_adv_conf': '获取游戏广告配置',
    'version.plist': '获取sdk配置',

    # #api.4399sy.com
    'authorize': '用户登录',
    'temp_key': '获取免注册登录验证key',
    'temp_login': '临号登录[如果临号不存在，则分配临号]',
    # 'auto_login':'用户自动接口',
    'silence_login': '添加账号登录',
    'reg': '注册账号[创建平台账号，注册日志]',
    'login_init': 'SDK初始化信息（登录完成调用）',
    'detect_bind_account': '获取账号绑定信息',
    'logout_info': '获取退出游戏界面数据',
    'get_info': '游戏包更新',
    'giftcode': '上传游戏礼包码',
    'config': '获取插件信息',
    'query_notice': '获取充值公告',
    'type': '获取充值方式',
    'money': '获取用户帐号余额',
    'bind': '绑定手机号',
    'get_sms': '短信验证码',
    'detect_phone_num': '检测手机号绑定情况',
    'check': '判断是否需要上传错误日志',
    'conf': 'SDK初始化登录类型',
    'coupon': '获取玩家可用代金券',
    'plugin': '获取插件对应的配置信息',
    'authentication_examine': '查询当前登录账号是否需要进行实名制认证',
    'authentication': '设置账号实名认证信息',
    'account_info': '第三方获取账号信息（触手）',
    'logout': '账号注销',
    'open_youxiquan': '打开游戏圈',
    'mycenter': '打开个人中心',
    'static': '获取静态资源[css,png]',
    'recover': '账号恢复',
    'nextUser': '切换账号',

    # #fnsdk.4399sy.com   fnapi.4399sy.com
    'login': '蜂鸟服务端登录验证[游戏合作商发起请求]',
    'order': '获取订单号[蜂鸟SDK生成订单号]',
    'update': '蜂鸟游戏包更新[获取最新的更新信息]',
    'fncfg': '蜂鸟初始化配置',
    'fncfg2': '蜂鸟初始化配置',
    'templogin': '蜂鸟临时帐号登录',
    'tempbind': '蜂鸟临时帐号绑定',
    'upload': '图片上传',
}

# 源点后台推送API
yd_log_type = {
    'MuTBIhzZOrALO0O0OBO0O0Om': '注册日志',
    'MuTBIhzZOrQLO0O0OBO0O0Om': '打开APP日志',
    'MuTBIh0ZMrALO0O0OBO0O0Om': '平台登陆日志',
    'MuTBIh0ZMrQLO0O0OBO0O0Om': '进服日志',
    'MuTBIh0ZMrgLO0O0OBO0O0Om': '创角日志',
    'MuTBIh0ZNrgLO0O0OBO0O0Om': '自定义事件表'
}

# 海外IOS 操作名（从path中获取，如get_user_server_login.php）
haiwai_action_from_path = {
    'activity_open': '打开游戏日志',
    'activity_before_login': '登录前日志',
    'load_start_before_login': '登录前加载开始日志',
    'load_finish_before_login': '登录前加载结束日志',
    'click_enter': '进入游戏日志',
    'enter_success': '成功进入游戏日志',
    'role_login': '角色登录日志',
    'get_user_server_login': '选服日志',
    'exit_success': '退出游戏日志',
    'user_create_role': '创角日志',
    'role_level': '角色升级日志',
    'user_online': '在线日志',
    'front_error': '前端错误日志',
}

# 海外Android 操作名（从body中获取）
haiwai_action_from_body = {
    'open_game': '打开游戏日志',
    'load_start_before_login': '登录前加载开始日志',
    'load_finish_before_login': '登录前加载结束日志',
    'open_login': '登录界面前日志',
    'role_login': '角色登录日志',
    'create_role': '创角日志',
    'enter_success': '成功进入游戏日志',
    'click_enter': '进入游戏日志',
    'select_server': '选服日志',
    'role_level_change': '角色等级日志',
    'exit_success': '退出游戏日志',
    'social_share': 'FB邀请功能埋点日志',

}

# 海外相关host
haiwai_host = [
    'dpdcs.4399sy.com.hk',
    'dpdcs.4399en.com',
    'dpdcs.4399th.com',
    'dpdcs.4399sy.ru',
    'dpdcs.moregame.vn'
]

api_host = [
    'api.demo.4399en.com',
    'api.4399en.com',
    'api.4399sy.com',
    'api-bgp.4399sy.com',
    'fnsdk.4399sy.com',
    'fnapi.4399sy.com',
    'api-bgp.4399sy.com'
]

# 排除path[-1] 的值
exclude_list = [
    'ico',
    'jpg',
    'png',
    'css',
    'js'
]


# redis连接池类，返回一个redis链接
class RedisPool:
    def __init__(self, host="127.0.0.1", port=6379, db=0):
        self.host = host
        self.port = port
        self.db = db

    def redis_connect(self):
        pool = redis.ConnectionPool(host=self.host, port=self.port, db=self.db)
        return redis.StrictRedis(connection_pool=pool)


P1 = RedisPool("127.0.0.1", 6379, 1)
R1 = P1.redis_connect()
P2 = RedisPool("127.0.0.1", 6379, 2)
R2 = P2.redis_connect()

startTime = None


def request(flow: http.HTTPFlow) -> None:
    global startTime
    CHANGE_AUTO_LOGIN_FLAG = 0
    client_id = flow.request.query.get("client_id")
    # 根据redis中设置的client_id_CHANGE_AUTO_LOGIN 开关值来判断是否走将自动登录修改为创建新玩家的模式路径，篡改请求信息
    if client_id:
        key_flag = client_id + "_CHANGE_AUTO_LOGIN"
        if R1.exists(key_flag):
            CHANGE_AUTO_LOGIN_FLAG = int(R1.get(key_flag))
        else:
            R1.set(key_flag, 0)
        currTime = datetime.datetime.now()
        longTime = 60
        if startTime:
            longTime = (currTime - startTime).seconds
        if (
                        flow.request.pretty_host == "api.4399sy.com" or flow.request.pretty_host == "api-bgp.4399sy.com") and \
                        flow.request.path_components[
                            -1] == "auto_login" and CHANGE_AUTO_LOGIN_FLAG == 1 and int(
            longTime) >= 60:
            startTime = datetime.datetime.now()
            did = flow.request.query.get("did")
            client_secret = flow.request.query.get("client_secret")
            from hashlib import md5
            m = md5()
            m.update(str(did + client_secret).encode("utf8"))
            sign = m.hexdigest()
            flow.request.query.add("sign", sign)
            flow.request.cookies.clear()
            flow.request.cookies.add("mitm", "false")
            flow.request.url = flow.request.pretty_url.replace(
                "service/user/auto_login", "oauth2/temp_login")


def response(flow: http.HTTPFlow) -> None:
    host = flow.request.host
    method = flow.request.method
    body = flow.request.data
    url = urllib.parse.unquote(flow.request.url)
    path = flow.request.path_components
    querystring = flow.request._get_query()
    game_id = None
    raw_msg = None
    action_type = None
    action_name = None
    status_code = None
    data_send = None
    ret = None
    plat = None
    project_id = None

    # 根据redis中设置的client_id_CHANGE_AUTO_LOGIN 开关值来判断是否走将自动登录修改为创建新玩家的模式路径,构造模拟返回信息
    CHANGE_AUTO_LOGIN_FLAG = 0
    client_id = flow.request.query.get("client_id")
    if client_id:
        key_flag = client_id + "_CHANGE_AUTO_LOGIN"
        if R1.exists(key_flag): CHANGE_AUTO_LOGIN_FLAG = int(R1.get(key_flag))
        if (
                        flow.request.pretty_host == "api.4399sy.com" or flow.request.pretty_host == "api-bgp.4399sy.com") and \
                        flow.request.path_components[
                            -1] == "temp_login" and CHANGE_AUTO_LOGIN_FLAG == 1:
            temp_login_resp = json.loads(flow.response.content.decode())
            auto_response = {
                "code": 300,
                "message": "change auto_login to regist ok",
                "result": {
                    "accessToken4399": "",
                    "username": temp_login_resp.get("username"),
                    "isTempAccount": 0,
                    "suid": temp_login_resp.get("suid"),
                    "verifyToken": temp_login_resp.get("verifyToken"),
                    "expires_in": temp_login_resp.get("expires_in"),
                    "bindPhone": 0,
                    "timestamp": temp_login_resp.get("timestamp"),
                    "signStr": temp_login_resp.get("signStr"),
                    "access_token": temp_login_resp.get("access_token"),
                    "uid": temp_login_resp.get("suid"),
                    "autoStr": temp_login_resp.get("autoStr"),
                    "targetServerId": -1,
                    "forcePayBack": 0
                }
            }
            flow.response = http.HTTPResponse.make(
                status_code=200,
                content=json.dumps(auto_response),
            )

    # 大陆联运日志，Android使用GET方法,iOS使用POST方法
    if host in ["udpdcs.4399sy.com", "adpdcs.4399sy.com"] and \
                    str(path[-1]).split(".")[-1] not in exclude_list:
        plat = "大陆联运"
        status_code = flow.response.status_code
        ret = flow.response.content
        # GET 方式 （联运Android）
        if method == "GET":
            # 从path中获取操作类型
            action_type = path[-1].rstrip(".php")
            action_name = udpdcs_action_from_path.get(
                action_type,
                "udpdcs_action_from_path[%s]" %
                action_type)
            # 从URL参数data中获取主要sdk请求数据
            data = {}
            for eachp in querystring:
                if eachp[0] == "data":
                    data = eachp[1]
                    try:
                        data_send = json.loads(data)
                        game_id = data_send.get('gameId')
                        # print("game_id:", game_id)
                        raw_msg = "大陆联运[%s],上报时间:%s:\n-->GET URL:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                            action_name, time.strftime("%Y-%m-%d %H:%M:%S",
                                                       time.localtime()), url,
                            status_code, ret)

                    except json.decoder.JSONDecodeError as e:
                        raw_msg = "大陆联运[%s]:\n-->GET 方法中的data内容转换json格式失败\n-->GET URL：%s" % (
                            action_name, url)
                        logging.error(raw_msg)
                    except Exception as e:
                        logging.error(e)
            # 从URL参数中匹配data参数失败
            if not data:
                raw_msg = "大陆联运[%s],上报时间:%s:\n-->GET URL：%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                    action_name,
                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), url,
                    status_code, ret)
        # POST 方式(联运iOS)
        else:
            # 从path中获取操作类型
            action_type = path[-1].rstrip(".php")
            action_name = udpdcs_action_from_path.get(
                action_type,
                "udpdcs_action_from_path[%s]" %
                action_type)
            # 从POST BODY 中匹配'data=(.*)\'$' 获得主要sdk请求数据
            raw_data = str(body.content)
            data_patten = re.compile('data=(.*)\'$', re.S)
            data_search = re.search(data_patten, raw_data)
            if data_search:
                data_send = urllib.parse.unquote(data_search.group(1))
                data_send = data_send.replace(
                    "\n",
                    "").replace(
                    "\t",
                    "").replace(
                    " ",
                    "")
                try:
                    # eg.
                    # data_send={"did":"83F6B45E-6DA9-4B78-9DC0-000278B44F84","gameId":"1483512079389590"
                    # ...}
                    data_send = json.loads(data_send)
                    game_id = data_send.get('gameId')
                    # print("game_id:", game_id)
                    raw_msg = "大陆联运[%s],上报时间:%s:\n-->POST URL:%s,\n-->POST DATA:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                        action_name,
                        time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                        url, data_send, status_code, ret)
                except json.decoder.JSONDecodeError as e:
                    raw_msg = "大陆联运[%s]:\n-->POST 方法中的POST DATA 内容转换json格式失败!\n-->POST URL:%s\n-->POST DATA:%s" % (
                        action_name, url, data_send)
                    logging.error(raw_msg)
                except Exception as e:
                    logging.error(e)
            # 从POST BODY 中匹配'data=(.*)\'$' 数据失败
            else:
                raw_msg = "大陆联运[%s]:\n-->POST 方法中的BODY data=内容获取失败!\n-->POST URL：%s\n-->POST DATA：%s" % (
                    action_name, url, urllib.parse.unquote(raw_data))
                logging.warning(raw_msg)
    # 大陆sy日志，Android，iOS使用POST方法
    elif host == "sdkdcs.4399sy.com":
        plat = "大陆SY"
        status_code = flow.response.status_code
        ret = flow.response.content
        if method == "POST":
            # 从POST BODY 中匹配'data=(.*)\'$' 获得主要sdk请求数据
            raw_data = str(body.content)
            data_patten = re.compile('data=(.*)\'$', re.S)
            data_search = re.search(data_patten, raw_data)
            if data_search:
                data_send = urllib.parse.unquote(data_search.group(1))
                data_send = data_send.replace(
                    "\n",
                    "").replace(
                    "\t",
                    "").replace(
                    " ",
                    "")
                try:
                    data = json.loads(data_send)
                    # eg. data={"data":{"common":{},"open_game":{}}}
                    data_send = data.get('data')
                    # eg. data_send={"common":{},"open_game":{}}
                    if data_send:
                        key_list = list(data_send.keys())
                        if "common" in key_list and len(key_list) == 2:
                            game_id = data_send.get("common").get("gameId")
                            # print("game_id:", game_id)
                            # 获取操作类型
                            key_list.remove("common")
                            action_type = key_list.pop(0)
                            action_name = sdkdcs_action_from_data.get(
                                action_type,
                                "sdkdcs_action_from_data[%s]" % action_type)
                            raw_msg = "大陆sy[%s],上报时间:%s:\n-->POST URL:%s \n-->POST DATA:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                                action_name, time.strftime("%Y-%m-%d %H:%M:%S",
                                                           time.localtime()),
                                url, data_send, status_code, ret)
                        else:
                            raw_msg = "大陆sy[]:\n-->BODY 字典中没有common这个key\n-->POST URL:%\n-->POST DATA：%s" % (
                                url, data_send)
                            logging.warning(raw_msg)
                    else:
                        raw_msg = "大陆sy[]:\n-->BODY 字典中没有data这个key \n-->POST URL:% \n-->POST DATA：%s" % (
                            url, data_send)
                        logging.warning(raw_msg)
                except json.decoder.JSONDecodeError as e:
                    raw_msg = "大陆sy[]:\n-->POST 方法中的POST DATA 内容转换json格式失败!\n-->POST URL:%s \n-->POST DATA:%s" % (
                        url, data_send)
                    logging.error(raw_msg)
                except Exception as e:
                    logging.error(e)

            # 从POST BODY 中匹配'data=(.*)\'$' 数据失败
            else:
                raw_msg = "大陆sy[]:\n-->POST 方法中的BODY data=内容获取失败!\n-->POST URL：%s\n-->POST DATA：%s" % (
                    url, urllib.parse.unquote(raw_data))
                logging.warning(raw_msg)
        else:
            raw_msg = "大陆sy[]:\n-->大陆日志使用了GET方式？\n-->GET URL：%s" % url
            logging.warning(raw_msg)
    # 海外IOS 使用POST方式，操作类型从path中获取，主要sdk请求参数从url中的data参数中获取
    # 海外android 使用POST方式，操作类型从body中获取，主要sdk请求参数从body中'data=(.*)\'$'中获取
    elif host in haiwai_host:
        plat = "海外平台"
        status_code = flow.response.status_code
        ret = flow.response.content
        if method == "POST":
            # 海外android SDK
            if body.content:
                # 从POST BODY 中匹配'data=(.*)\'$' 获得主要sdk请求数据
                raw_data = str(body.content)
                data_patten = re.compile('data=(.*)\'$', re.S)
                data_search = re.search(data_patten, raw_data)
                if data_search:
                    data_send = urllib.parse.unquote(data_search.group(1))
                    data_send = data_send.replace(
                        "\n",
                        "").replace(
                        "\t",
                        "").replace(
                        " ",
                        "")
                    try:
                        data = json.loads(data_send)
                        # eg. data={"data":{"common":{},"open_game":{}}}
                        data_send = data.get('data')
                        if data_send:
                            key_list = list(data.keys())
                            if "common" in key_list and len(key_list) == 2:
                                game_id = data.get("common").get("gameId")
                                # print("game_id:", game_id)
                                # 获取操作类型
                                key_list.remove("common")
                                action_type = key_list.pop(0)
                                action_name = haiwai_action_from_body.get(
                                    action_type,
                                    "haiwai_action_from_body[%s]" % action_type)
                                raw_msg = "海外Android[%s],上报时间:%s:\n-->POST URL:%s \n-->POST DATA:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                                    action_name,
                                    time.strftime("%Y-%m-%d %H:%M:%S",
                                                  time.localtime()), url,
                                    data_send, status_code, ret)
                            else:
                                raw_msg = "海外Android[]:\n-->BODY 字典中没有common这个key\n-->POST URL:%\n-->POST DATA：%s" % (
                                    url, data_send)
                                logging.warning(raw_msg)
                        else:
                            raw_msg = "海外Android[]:\n-->BODY 字典中没有data这个key \n-->POST URL:% \n-->POST DATA：%s" % (
                                url, data_send)
                            logging.warning(raw_msg)
                    except json.decoder.JSONDecodeError as e:
                        raw_msg = "海外Android[]:\n-->POST 方法中的POST DATA 内容转换json格式失败!\n-->POST URL:%s \n-->POST DATA:%s" % (
                            url, data_send)
                        logging.error(raw_msg)
                    except Exception as e:
                        logging.error(e)

                # 从POST BODY 中匹配'data=(.*)\'$' 数据失败
                else:
                    raw_msg = "海外Android[]:\n-->POST 方法中的BODY data=内容获取失败!\n-->POST URL：%s\n-->POST DATA：%s" % (
                        url, urllib.parse.unquote(raw_data))
                    logging.warning(raw_msg)
            # 海外IOS SDK
            else:
                # 从path中获取操作类型
                action_name = ""
                action_type = ""
                if path:
                    action_type = path[-1].rstrip(".php")
                    action_name = haiwai_action_from_path.get(
                        action_type, "haiwai_action_from_path[%s]" %
                                     action_type)
                # 从URL参数data中获取主要sdk请求数据
                data = {}
                for eachp in querystring:
                    if eachp[0] == "data":
                        data = eachp[1]
                        try:
                            data_send = json.loads(data)
                            # eg. data_send={"gameId":"1416549966640860","did":"285F61B2"}
                            game_id = data_send.get('gameId')
                            # print("game_id:", game_id)
                            raw_msg = "海外IOS[%s],上报时间:%s:\n-->POST URL:%s \n-->POST DATA:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                                action_name, time.strftime("%Y-%m-%d %H:%M:%S",
                                                           time.localtime()),
                                url, data_send, status_code, ret)
                        except json.decoder.JSONDecodeError as e:
                            raw_msg = "海外IOS[%s]:\n-->URL中的data内容转换json格式失败\n-->POST URL：%s" % (
                                action_name, url)
                            logging.error(raw_msg)
                        except Exception as e:
                            logging.error(e)
                # 从URL参数中匹配data参数失败
                if not data:
                    raw_msg = "海外IOS[%s]:\n-->URL中的data内容获取失败，\n-->POST URL：%s" % (
                        action_name, url)
                    logging.warning(raw_msg)

        # 海外GET方法，如在线online.php
        else:
            # 从path中获取操作类型
            action_name = ""
            action_type = ""
            if path:
                action_type = path[-1].rstrip(".php")
                action_name = haiwai_action_from_path.get(
                    action_type, "haiwai_action_from_path[%s]" %
                                 action_type)
            # 从URL参数data中获取主要sdk请求数据
            data = {}
            for eachp in querystring:
                if eachp[0] == "data":
                    data = eachp[1]
                    try:
                        data_send = json.loads(data)
                        # eg. data_send={"gameId":"1416549966640860","did":"285F61B2"}
                        game_id = data_send.get('gameId')
                        # print("game_id:", game_id)
                        raw_msg = "海外[%s],上报时间:%s:\n-->GET URL:%s \n-->GET DATA:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                            action_name, time.strftime("%Y-%m-%d %H:%M:%S",
                                                       time.localtime()), url,
                            data_send, status_code, ret)
                    except json.decoder.JSONDecodeError as e:
                        raw_msg = "海外[%s]:\n-->URL中的data内容转换json格式失败\n-->GET URL：%s" % (
                            action_name, url)
                        logging.error(raw_msg)
                    except Exception as e:
                        logging.error(e)
            # 从URL参数中匹配data参数失败
            if not data:
                raw_msg = "海外[%s]:\n-->URL中的data内容获取失败，\n-->GET URL：%s" % (
                    action_name, url)
                logging.warning(raw_msg)
    # api关键操作
    elif host in api_host:
        plat = "API操作"
        status_code = flow.response.status_code
        ret = flow.response.content
        # 获取gameId
        for eachp in querystring:
            if eachp[0] == "client_id":
                game_id = eachp[1]
                # print("game_id:", game_id)
        # API GET ...
        if method == "GET":
            # 从path中获取操作类型
            action_type = path[-1].rstrip(".php")
            data_send = querystring
        # API POST ...
        else:
            # api.4399sy.com 安卓 POST,例如https://api.4399sy.com/u/?_a=XXX
            # api.4399sy.com iOS POST，例如:https://api.4399sy.com/service/user/auto_login?xx=xx
            action_type = path[-1]
            data_send = body.content

        if action_type == 'u':
            for eachp in querystring:
                if eachp[0] in ["_a", "_c"]:
                    action_type = eachp[1]
        # 选取倒数第二个文件名作为操作类型，如
        # POST URL:https://api.4399sy.com/service/giftcode/save/ 礼包激活日志
        if action_type in ['save', 'data', 'main']:
            if len(path) >= 2:
                action_type = path[-2]
        # 静态资源
        if str(action_type).endswith(".css") or str(action_type).endswith(
                ".png"):
            action_type = "static"

        action_name = api_action_from_path.get(
            action_type,
            "api_action_from_path[%s]" %
            action_type)
        raw_msg = "API操作[%s],上报时间:%s:\n-->%s URL:%s\n-->POST DATA:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
            action_name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
            method, url, data_send, status_code, ret)

    # 源点API推送
    elif host in ["b.533y.com"] and path == ('datacf', 'api', 'push'):
        plat = "源点推送"
        status_code = flow.response.status_code
        ret = flow.response.content
        raw_msg = ""
        for eachp in querystring:
            # 获取日志类型
            if eachp[0] == "tid":
                action_type = eachp[1]
                action_name = yd_log_type.get(action_type)
            if eachp[0] == "data":
                data = eachp[1]
                # 获取gameId
                data_send = json.loads(data)
                game_id = data_send.get('gameid')
            # 获取projectid
            if eachp[0] == "projectid":
                project_id = eachp[1]
        if game_id:
            raw_msg = "源点上报[%s],上报时间:%s:\n-->GET URL:%s\n-->STATUS CODE:%s\n-->RESPONSE:%s" % (
                action_name,
                time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), url,
                status_code, ret)
    else:
        pass

    # 输出日志
    if raw_msg:
        if data_send:
            if len(data_send) == 0:
                data_send = str(data_send)
            if isinstance(data_send, bytes):
                data_send = data_send.decode("utf-8")
                if "client_id" in data_send:
                    match = re.search("client_id=(\d+)&", data_send)
                    if match:
                        game_id = match.group(1)
        else:
            data_send = ""

        try:
            ret = json.loads(ret.decode('utf-8'))
        except Exception as e:
            ret = str(ret)
        dict_msg = {
            "plat": plat,
            "project_id": project_id,
            "host": host,
            "method": method,
            "url": url,
            "action_type": action_type,
            "action_name": action_name,
            "data": data_send,
            "action_time": datetime.datetime.now().strftime(
                '%Y-%m-%d %H:%M:%S.%f'),
            "status_code": status_code,
            "response": ret
        }
        print("game_id:%s" % game_id)
        print("raw_msg:", raw_msg)
        print("dict_msg:", dict_msg)
        logging.info(raw_msg)
        publish_log(game_id, raw_msg, dict_msg)


# 发布日志
def publish_log(game_id, raw_msg, dict_msg):

    if game_id:
        # 保存到redis列表中，数据持久化
        key = game_id + "_" + str(datetime.datetime.now().strftime("%Y%m%d"))
        # 保存原始请求字符串
        R1.lpush(key, raw_msg)
        # 保存处理后的请求字典
        if dict_msg:
            R2.lpush(key, json.dumps(dict_msg))
            # 设置redis有效期2天 -2 已过期 -1 一直有效
            # if int(R.ttl(game_id)) < 0:
            #    R.expire(game_id, 172800)
        # 发布到redis频道game_id
        R1.publish(game_id, json.dumps(dict_msg))
        print("发布到redis频道game_id:",game_id)
